package com.xgq.drink.config;

import com.xgq.drink.entity.Role;
import com.xgq.drink.utils.JwtTokenUtil;
import com.xgq.drink.utils.RedisUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtil jwtUtil;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private RedisUtil redisUtil;
    //这是过滤器的核心方法，用于处理每个 HTTP 请求，并执行以下逻辑：
    //提取 Token：通过 resolveToken 方法从请求头中提取 JWT Token。
    //检查 Token 是否在黑名单中：调用 isTokenBlacklisted 方法检查 Token 是否被加入黑名单。
    //验证 Token 并设置认证信息：如果 Token 有效且不在黑名单中，提取 Token 中的用户名，并创建一个 UsernamePasswordAuthenticationToken 对象，将其设置到 SecurityContextHolder 中，从而完成用户认证。
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        System.out.println("!!!!!!!!!!!!!!!!!!!!");
        // 清除旧的认证信息
        SecurityContextHolder.clearContext();
        
        String token = resolveToken(request);
        System.out.println("token"+token);
        if (token != null && !isTokenBlacklisted(token)) {
            String userId = jwtUtil.getUserIdFromToken(token);
            System.out.println(userId);
            if (userId != null) {
                // 从Redis中获取用户角色
                List<Role> roles = redisUtil.getUserRoles(userId);
                List<GrantedAuthority> authorities = new ArrayList<>();
                
                if (roles != null && !roles.isEmpty()) {
                    // 将角色信息转换为GrantedAuthority列表
                    authorities = roles.stream()
                            .map(role -> new SimpleGrantedAuthority("ROLE_" + role.getCode()))
                            .collect(Collectors.toList());
                }
                System.out.println(authorities);
                // 创建Authentication对象并设置到SecurityContext
                UsernamePasswordAuthenticationToken authentication =
                        new UsernamePasswordAuthenticationToken(userId, null, authorities);
                SecurityContextHolder.getContext().setAuthentication(authentication);
                System.out.println("OK");
            }
        }
        chain.doFilter(request, response);
    }

    private String resolveToken(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }

    private boolean isTokenBlacklisted(String token) {
        return Boolean.TRUE.equals(redisTemplate.hasKey(token));
    }
}